package dream.flying.flower.enums;

/**
 * 常用字符串校验枚举
 *
 * <pre>
 * ():组,包含一个表达式,里面的字符被认为是一个整体
 * \:转义,将下一个字符标记符,或一个向后引用,或一个八进制转义符转义.
 * 		转义:如\\表示匹配一个\,\"表示转义双引号等
 * 		向后引用:\\n表示n所在的位置匹配前面的第n组(第n个()),如:(e)\\1,匹配ee;(e)(l)\\2,匹配ell;(e)(l)\\1匹配ele
 * ^:匹配开头字符,在[]里面表示非,不匹配
 * $:匹配结尾字符
 * *:匹配任意次数的表达式,包括0,1,N次
 * +:匹配一次及以上的表达式
 * ?:匹配0次或1次表达式.当?紧跟*,+,?,{n},{n,},{n,m}时,只会匹配最少字符串,默认是匹配最多字符串.
 * 		如:ooooo,o+得到的是ooooo,o+?得到的是o
 * {n}:n大于0,匹配n次表达式,只能是n次
 * {n,}:匹配大于等于n次表达式
 * {n,m}:匹配大于等于n次表达式,小于等于m次表达式
 * (pattern):匹配pattern并获得这一匹配,获得可使用$0...$9
 * (?:pattern):匹配pattern,但是不获取匹配结果
 * x|y:匹配x或y
 * [abc]:匹配abc中的任意一个字符即可
 * [^abc]:不匹配abc中的任意一个字符
 * \b:匹配一个单词的边界,即匹配的字符前或后必须是空格或制表符等
 *		如:er\b可以匹配never,但不能匹配verv
 * \B:和\b正好相反
 * \s:匹配任何不可见字符,包括空格,制表符,换行符等
 * \S:匹配任何可见字符,除\s之外的字符
 * .:匹配单个任意字符,除了\n,\r.要匹配包括\n,\r在内的字符,可使用[\s\S]
 * \w:任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
 * \d:任意一个数字,0~9 中的任意一个
 * </pre>
 * 
 * 需要转义的字符串
 * 
 * <pre>
 * \^ , \$, \., \(, \) , \{, \} , \? , \+ , \* , \| ,\[, \]
 * </pre>
 *
 * @author 飞花梦影
 * @date 2023-11-07 15:26:02
 * @git {@link https://github.com/dreamFlyingFlower}
 */
public enum RegexEnum {

	/** 英文和数字 */
	REGEX_ENGNUM("^[A-Za-z0-9]+$"),

	/** 检查是否全中文,不包括标点符号等 */
	REGEX_CHINA("^[\\u4E00-\\u9FA5]*$"),

	/** 中英文和数字,下划线 */
	REGEX_CHENNUM("^[\\u4E00-\\u9FA5A-Za-z0-9_]*$"),

	/** 检查手机号 */
	REGEX_PHONE("\\d{3}-\\d{8}|1\\d{10}"),

	/** 检查是否邮箱 */
	REGEX_EMAIL("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*"),

	/** 身份证,18位和15位 */
	REGEX_IDCARD("^[1-9]\\d{5}[12]\\d{3}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)"
			+ "|(^[1-9]\\d{5}\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{2}$"),

	/** QQ号 */
	REGEX_QQ("[1-9][0-9]{4,}"),

	/** 邮编 */
	REGEX_ZIPCODE("[1-9]\\d{5}(?!\\d)"),

	/** 是否为货币 */
	REGEX_MONEY("^(\\d+(?:\\.\\d+)?)$"),

	/** 数字 */
	REGEX_NUMBER("\\d+"),

	/**
	 * 判断字符串是否为统一社会信用代码（18位）<br>
	 * 统一代码由十八位的阿拉伯数字或大写英文字母（不使用I、O、Z、S、V）组成。<br>
	 * 第1位：登记管理部门代码（共一位字符）[1、5、9、Y]<br>
	 * 第2位：机构类别代码（共一位字符）[与第一位合并成，11、12、13、19、51、52、53、59、91、92、93、Y1]组成。<br>
	 * 第3位~第8位：登记管理机关行政区划码（共六位阿拉伯数字）[100000~999999]<br>
	 * 第9位~第17位：主体标识码（组织机构代码）（共九位字符）<br>
	 * 第18位：校验码​（共一位字符）<br>
	 */
	REGEX_USCC("^(11|12|13|19|51|52|53|59|91|92|93|Y1)[1-9]{1}[0-9]{5}[0-9A-HJ-NP-RT-UW-Y0-9]{9}[0-90-9A-HJ-NP-RT-UW-Y]{1}$"),

	/** 银联帐号 */
	REGEX_UNIONPAYCARD("^62[0-5]\\d{13,16}$"),

	/** 符合yyyy-MM-dd日期格式的时间字符串 */
	REGEX_DATE("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$"),

	/** 符合yyyy/MM/dd日期格式的时间字符串 */
	REGEX_DATE_SLASH("^\\d{4}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])$"),

	/** 符合yyyyMMdd日期格式的时间字符串 */
	REGEX_DATE_NONE("^\\d{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$"),

	/** 符合yyyy-MM-dd HH:mm:ss日期格式的时间字符串 */
	REGEX_DATETIME("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) ([0-1][0-9]|2[0-3])(:[0-5][0-9]){2}$"),

	/** 符合yyyy/MM/dd HH:mm:ss日期格式的时间字符串 */
	REGEX_DATETIME_SLASH("^\\d{4}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1]) ([0-1][0-9]|2[0-3])(:[0-5][0-9]){2}$"),

	/** 符合yyyyMMdd HH:mm:ss日期格式的时间字符串 */
	REGEX_DATETIME_NONE("^\\d{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1]) ([0-1][0-9]|2[0-3])(:[0-5][0-9]){2}$"),

	/** 匹配双字节字符,包括汉字.可以用来计算字符串的长度,一个双字节字符长度计2,ASCII字符计1 FIXME */
	REGEX_DOUBLE_CHAR("[^\\x00-\\xff]"),

	/** 匹配多个空白行 */
	REGEX_BLANK("[\\n\\s*\\r]+"),

	/** 匹配首尾空白字符 */
	REGEX_BLANK_BEGIN_END("^\\s*(.)+|(.)+\\s*$"),

	/** 匹配网址URL FIXME */
	REGEX_URL("[a-zA-z]+://[^\\s]*"),

	/** 匹配IPV4地址 FIXME */
	REGEX_NETWORK_IPV4("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"),

	/** 匹配IPV6地址 FIXME */
	REGEX_NETWORK_IPV6("(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:"
			+ "|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}"
			+ "|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}"
			+ "|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})"
			+ "|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}"
			+ "|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]"
			+ "|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]"
			+ "|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"),

	/** 匹配子网掩码 FIXME */
	REGEX_NETWORK_MASK("((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))"),

	/** 匹配HTML标记,只能匹配一部分,复杂的仍然不能匹配 */
	REGEX_HTML_TAG("<(\\S*?)[^>]*>.*?</\\1>|<.*? />"),

	/** 匹配HTML页面img标签中的src属性 FIXME */
	REGEX_HTML_IMG_SRC("\\< *[img][^\\>]*[src] *= *[\"\']{0,1}([^\"\'\\ >]*)"),

	/** 匹配HTML页面a标签中的超链接 FIXME */
	REGEX_HTML_A_HREF("(<a\\s*(?!.*\\brel=)[^>]*)(href=\"https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?', $follow_list).'))[^\" rel=\"external nofollow\" ]+)\"((?!.*\\brel=)[^>]*)(?:[^>]*)>");

	private String regex;

	RegexEnum(String regex) {
		this.regex = regex;
	}

	@Override
	public String toString() {
		return regex;
	}
}